import {
  Injectable,
  NotFoundException,
  ConflictException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreatePermissionDto } from './dto/create-permission.dto';
import { UpdatePermissionDto } from './dto/update-permission.dto';
import { Permission } from './permission.entity';

/**
 * 权限服务
 * 处理权限相关的业务逻辑
 */
@Injectable()
export class PermissionsService {
  constructor(
    @InjectRepository(Permission)
    private permissionRepository: Repository<Permission>,
  ) {}

  /**
   * 创建权限
   * @param createPermissionDto 创建权限数据
   * @returns 创建的权限信息
   */
  async create(createPermissionDto: CreatePermissionDto): Promise<Permission> {
    const { name, description, resource, action } = createPermissionDto;

    // 检查权限名是否已存在
    const existingPermission = await this.permissionRepository.findOne({
      where: { name },
    });
    if (existingPermission) {
      throw new ConflictException('权限名已存在');
    }

    // 创建权限
    const permission = this.permissionRepository.create({
      name,
      description,
      resource,
      action,
    });

    return this.permissionRepository.save(permission);
  }

  /**
   * 获取权限列表
   * @param page 页码
   * @param limit 每页数量
   * @returns 权限列表和总数
   */
  async findAll(page: number = 1, limit: number = 10) {
    const [permissions, total] = await this.permissionRepository.findAndCount({
      skip: (page - 1) * limit,
      take: limit,
      order: { createdAt: 'DESC' },
    });

    return {
      data: permissions,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit),
    };
  }

  /**
   * 获取权限详情
   * @param id 权限ID
   * @returns 权限详情
   */
  async findOne(id: number): Promise<Permission> {
    const permission = await this.permissionRepository.findOne({
      where: { id },
      relations: ['roles'],
    });

    if (!permission) {
      throw new NotFoundException('权限不存在');
    }

    return permission;
  }

  /**
   * 更新权限信息
   * @param id 权限ID
   * @param updatePermissionDto 更新数据
   * @returns 更新后的权限信息
   */
  async update(
    id: number,
    updatePermissionDto: UpdatePermissionDto,
  ): Promise<Permission> {
    const permission = await this.findOne(id);
    const { name, description, resource, action } = updatePermissionDto;

    // 如果更新权限名，检查是否已存在
    if (name && name !== permission.name) {
      const existingPermission = await this.permissionRepository.findOne({
        where: { name },
      });
      if (existingPermission) {
        throw new ConflictException('权限名已存在');
      }
    }

    // 更新基本信息
    if (name) permission.name = name;
    if (description !== undefined) permission.description = description;
    if (resource) permission.resource = resource;
    if (action) permission.action = action;

    return this.permissionRepository.save(permission);
  }

  /**
   * 删除权限
   * @param id 权限ID
   */
  async remove(id: number): Promise<void> {
    const permission = await this.findOne(id);

    // 检查是否有角色关联此权限
    if (permission.roles && permission.roles.length > 0) {
      throw new ConflictException('该权限还被角色使用，无法删除');
    }

    await this.permissionRepository.remove(permission);
  }

  /**
   * 切换权限状态
   * @param id 权限ID
   * @returns 更新后的权限信息
   */
  async toggleStatus(id: number): Promise<Permission> {
    const permission = await this.findOne(id);
    permission.isActive = !permission.isActive;
    return this.permissionRepository.save(permission);
  }

  /**
   * 根据资源和操作查找权限
   * @param resource 资源
   * @param action 操作
   * @returns 权限信息
   */
  async findByResourceAndAction(
    resource: string,
    action: string,
  ): Promise<Permission | null> {
    return this.permissionRepository.findOne({
      where: { resource, action },
    });
  }

  /**
   * 获取所有激活的权限
   * @returns 激活的权限列表
   */
  async findAllActive(): Promise<Permission[]> {
    return this.permissionRepository.find({
      where: { isActive: true },
      order: { resource: 'ASC', action: 'ASC' },
    });
  }
}